package Busquedas;

import Problemas.Problema;
import java.util.ArrayList;

/**
 * Clase para implementar la busqueda de profundidad limitada.
 * Extiende de la clase Busqueda.

 */
public class ProfundidadLimitada extends Busqueda {

	private int limite;
	

	public ProfundidadLimitada(Problema p,int lim) {
		super(p);
		limite=lim;
	}


	public ArrayList<Estado> buscar(boolean controlCiclos){
		int nivelActual=0;
		abiertos.add(this.getNodo()); 
		expandidos.add(this.getNodo().getEstado());
		Nodo n;
		int op=0;
		long tiempo1=System.currentTimeMillis();
		try{	
			while((!abiertos.isEmpty())&& (nivelActual<=limite)){
				contadorNodos++;
				if (contadorNodos>maxContadorNodos) return null;
				n = abiertos.get(abiertos.size()-1);
				if (!this.getProblema().estadoFinal(n.getEstado())){
					if ((op==this.getProblema().getnumOper())|| (nivelActual==limite)){					
						abiertos.remove(abiertos.size()-1);
						n=n.getPadre();
						nivelActual--;
						op=0;
						
					}else if (n.getOperadoresAplicados()[op]==1){
						op++;
					}else {
						Estado e=this.getProblema().aplicaOperador(n.getEstado(), op);
						n.setOperadoresAplicados(op);
						if (e!=null){
							if ((!(controlCiclos && estaEnExpandidos(e)))&& (nivelActual<limite)){
								Nodo n2=n.anadeHijo(op,e,this.getProblema().getCosteOperador(op));
								abiertos.add(n2);
								nivelActual++;
								expandidos.add(n.getEstado());
								int inverso = this.getProblema().getOperadorInverso(op);
								if (inverso != -1) 
									n2.setOperadoresAplicados(inverso);
								op=0;
							}
						}else {
							op++;
						}
					}
				}else{
					long tiempo2=System.currentTimeMillis();
					this.setTiempoTotal((tiempo2-tiempo1));
					generaCamino(n);
					return camino;
				}		
			}
		}catch(OutOfMemoryError e){
			abiertos = null;
			return null;
		}
		return null;
	}
	

}
